home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PRINTER
/
HPMAZE02.ARJ
/
HP3DMAZE.C
< prev
next >
Wrap
Text File
|
1991-04-24
|
49KB
|
1,261 lines
/*
This program will generate a three dimensional maze suitable for
printing on a Hewlett-Packard LaserJet II printer. A different random
number seed will produce a different maze.
Written by James L. Dean
406 40th Street
New Orleans, LA 70124
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <malloc.h>
#define TRUE 1
#define FALSE 0
#define EBCDIC 0
/* printer constants */
#define DOTS_PER_INCH 150
#define WIDTH_IN_INCHES 8.5
#define LENGTH_IN_INCHES 11.0
#define DOTS_PER_STROKE 2 /* 300/DOTS_PER_INCH */
#define NUM_X_BYTES 206 /* (int) (LENGTH_IN_INCHES*DOTS_PER_INCH/8) */
#define X_BYTE_MAX 205 /* NUM_X_BYTES-1 */
#define NUM_X_DOTS 1648 /* 8*NUM_X_BYTES */
#define X_DOT_MAX 1647 /* NUM_X_DOTS-1 */
#define NUM_Y_DOTS 1275 /* (int) (WIDTH_IN_INCHES*DOTS_PER_INCH) */
#define Y_DOT_MAX 1274 /* NUM_Y_DOTS-1 */
#define NUM_SLICES 3 /* smaller values run faster, use more memory */
#define ROWS_PER_SLICE 425 /* (NUM_Y_DOTS+NUM_SLICES-1)/NUM_SLICES */
/* maze constants */
#define MIN_DOTS_PER_ROOM_WALL 40
#define NUM_COLUMNS 20 /* <= NUM_X_DOTS/MIN_DOTS_PER_ROOM_WALL */
#define MAX_X 40 /* 2*NUM_COLUMNS */
#define MAX_X_PLUS_1 41 /* MAX_X+1 */
#define NUM_ROWS 15 /* <= NUM_Y_DOTS/MIN_DOTS_PER_ROOM_WALL */
#define MAX_Y 30 /* 2*NUM_ROWS */
#define MAX_Y_PLUS_1 31 /* MAX_Y+1 */
/* ((double) NUM_COLUMNS)/((double) NUM_ROWS) should be approximately
LENGTH_IN_INCHES/WIDTH_IN_INCHES.
Memory requirements and run time increase with NUM_COLUMNS*NUM_ROWS.
*/
typedef struct pointtype_record
{
int x;
int y;
} pointtype;
typedef struct prime_rec_record *prime_rec_ptr;
typedef struct prime_rec_record
{
double x;
double y;
double z;
char base_z;
prime_rec_ptr left;
prime_rec_ptr right;
prime_rec_ptr down;
prime_rec_ptr lesser_x;
prime_rec_ptr greater_x;
} prime_rec;
typedef struct row_type_record
{
unsigned char column [NUM_X_BYTES];
} row_type;
typedef row_type *row_ptr_type;
typedef struct up_rec_record *up_rec_ptr;
typedef struct up_rec_record
{
prime_rec_ptr up;
up_rec_ptr next;
up_rec_ptr previous;
} up_rec;
static void add_room(void);
static void adjust_perspective(prime_rec_ptr *,prime_rec_ptr *,
prime_rec_ptr *,double *,double *,double *,double *,double *,
int *);
static void draw_line(int *,int *,int *,int *,int);
static void evaluate_and_transform(double *,double *,double *,double *,int *,
int *,double *,double *,prime_rec_ptr *,prime_rec_ptr *,
prime_rec_ptr *,double *,double *,double *,double *,double *,
int *);
static double f(double,double);
void main(void);
static void plot(prime_rec_ptr *,double *,double *,double *,double *,int *,
int *);
static void pset(int *,int *,int);
static unsigned char black [8] = {128, 64, 32, 16, 8, 4, 2, 1};
static int delta_x [4] [24];
static int delta_y [4] [24];
static char page [MAX_Y_PLUS_1] [MAX_X_PLUS_1];
static int r_n [8];
static int r_n_index_1;
static int r_n_index_2;
static row_ptr_type row_ptr [ROWS_PER_SLICE];
static int slice_y;
static int slice_y_start;
static int slice_y_stop;
static int tem_int;
static unsigned char white [8] = {127, 191, 223, 239, 247, 251, 253, 254};
static int x;
static double x_max;
static int x_next;
static int x_wall_1;
static int y;
static int y_next;
static int y_wall_1;
void main(void)
{
static unsigned char ascii_equivalent [6];
#if EBCDIC
static unsigned char *char_ptr;
#endif
register int column_num;
static int cursor_x;
static char cursor_x_prefix [3] = {'\033', '\052', '\160'};
static char cursor_x_suffix = '\130';
static int cursor_y;
static char cursor_y_prefix [3] = {'\033', '\052', '\160'};
static char cursor_y_suffix = '\131';
static int delta_index_1a;
static int delta_index_1b;
static int delta_index_1c;
static int delta_index_1d;
static int delta_index_2;
static int digit;
static int digit_num;
static char dpi_prefix [3] = {'\033', '\052', '\164'};
static char dpi_suffix = '\122';
register int ending_column_num;
static int fatal_error;
static char formfeed = '\014';
static char landscape [5]
= {'\033', '\046', '\154', '\061', '\117'};
static char logical_mode [5]
= {'\033', '\052', '\162', '\060', '\106'};
static int max_y_out;
static int max_z_out;
FILE *maze;
static int non_null_found;
static int num_bytes;
static int num_x_divisions;
static int num_y_divisions;
static prime_rec_ptr prime_cornor;
static prime_rec_ptr prime_head;
static prime_rec_ptr prime_ptr;
static prime_rec_ptr prime_tail;
static char raster_prefix [5]
= {'\033', '\052', '\162', '\061', '\101'};
static char raster_suffix [4]
= {'\033', '\052', '\162', '\102'};
static double rotation;
static int row_num;
static char row_prefix [3] = {'\033', '\052', '\142'};
static char row_suffix = '\127';
static char seed [256];
static int seed_length;
static int starting_column_num;
static int sum;
static double tilt;
static double x_min;
static int x_out;
static double x_prime_max;
static double y_max;
static double y_min;
static int y_out;
static double y_prime_max;
static double y_prime_min;
static double z_prime_max;
static double z_prime_min;
fatal_error=FALSE;
printf("\n The maze will be outputted to HP3DMAZE.\n\n");
printf(" Random number seed? ");
gets(&seed[0]);
seed_length=strlen(&seed[0]);
for (r_n_index_1=0; r_n_index_1 < seed_length; ++r_n_index_1)
{
tem_int=(int) seed[r_n_index_1];
while (tem_int >= 29)
tem_int-=29;
r_n[r_n_index_1]=tem_int;
}
r_n_index_2=7;
while (r_n_index_1 > 0)
{
r_n_index_1--;
r_n[r_n_index_2]=r_n[r_n_index_1];
r_n_index_2--;
}
while (r_n_index_2 >= 0)
{
r_n[r_n_index_2]=19;
r_n_index_2--;
}
delta_x[0][0]=-1;
delta_y[0][0]=0;
delta_x[1][0]=0;
delta_y[1][0]=1;
delta_x[2][0]=1;
delta_y[2][0]=0;
delta_x[3][0]=0;
delta_y[3][0]=-1;
delta_index_2=0;
for (delta_index_1a=0; delta_index_1a < 4; ++delta_index_1a)
for (delta_index_1b=0; delta_index_1b < 4; ++delta_index_1b)
if (delta_index_1a != delta_index_1b)
for (delta_index_1c=0; delta_index_1c < 4; ++delta_index_1c)
if ((delta_index_1a != delta_index_1c)
&& (delta_index_1b != delta_index_1c))
for (delta_index_1d=0; delta_index_1d < 4; ++delta_index_1d)
if ((delta_index_1a != delta_index_1d)
&& (delta_index_1b != delta_index_1d)
&& (delta_index_1c != delta_index_1d))
{
delta_x[delta_index_1a][delta_index_2]=delta_x[0][0];
delta_y[delta_index_1a][delta_index_2]=delta_y[0][0];
delta_x[delta_index_1b][delta_index_2]=delta_x[1][0];
delta_y[delta_index_1b][delta_index_2]=delta_y[1][0];
delta_x[delta_index_1c][delta_index_2]=delta_x[2][0];
delta_y[delta_index_1c][delta_index_2]=delta_y[2][0];
delta_x[delta_index_1d][delta_index_2]=delta_x[3][0];
delta_y[delta_index_1d][delta_index_2]=delta_y[3][0];
delta_index_2++;
}
for (row_num=0; ((row_num < ROWS_PER_SLICE) && (! fatal_error));
++row_num)
{
if ((row_ptr[row_num]=(row_type *) malloc(sizeof(row_type))) == NULL)
{
fatal_error=TRUE;
printf("\n Fatal error: out of memory\n");
}
}
if (! fatal_error)
{
max_y_out=X_DOT_MAX;
max_z_out=Y_DOT_MAX;
for (y_out=0; y_out <= MAX_Y; ++y_out)
for (x_out=0; x_out <= MAX_X; ++x_out)
page[y_out][x_out]='W';
sum=0;
for (digit_num=1; digit_num <= 3; ++digit_num)
{
digit=r_n[0];
r_n_index_1=0;
for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
{
tem_int=r_n[r_n_index_2];
r_n[r_n_index_1]=tem_int;
digit+=tem_int;
if (digit >= 29)
digit-=29;
r_n_index_1=r_n_index_2;
}
r_n[7]=digit;
sum=29*sum+digit;
}
x=2*(sum % NUM_COLUMNS)+1;
sum=0;
for (digit_num=1; digit_num <= 3; ++digit_num)
{
digit=r_n[0];
r_n_index_1=0;
for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
{
tem_int=r_n[r_n_index_2];
r_n[r_n_index_1]=tem_int;
digit+=tem_int;
if (digit >= 29)
digit-=29;
r_n_index_1=r_n_index_2;
}
r_n[7]=digit;
sum=29*sum+digit;
}
y=2*(sum % NUM_ROWS)+1;
add_room();
page[0][1]=' ';
page[MAX_Y][MAX_X-1]=' ';
x_min=1.0;
x_max=(double) MAX_Y;
x_max=2.0*x_max+5.0;
y_min=1.0;
y_max=(double) MAX_X;
y_max=2.0*y_max+5.0;
num_x_divisions=2*MAX_Y+5;
num_y_divisions=2*MAX_X+5;
prime_head=NULL;
rotation=20.0;
tilt=30.0;
evaluate_and_transform(&x_min,&x_max,&y_min,&y_max,&num_x_divisions,
&num_y_divisions,&rotation,&tilt,&prime_cornor,&prime_head,
&prime_tail,&x_prime_max,&y_prime_min,&y_prime_max,&z_prime_min,
&z_prime_max,&fatal_error);
}
if (! fatal_error)
adjust_perspective(&prime_cornor,&prime_head,&prime_tail,&x_prime_max,
&y_prime_min,&y_prime_max,&z_prime_min,&z_prime_max,&fatal_error);
if (! fatal_error)
{
maze=fopen("HP3DMAZE","wb");
fwrite(landscape,sizeof(landscape),1,maze);
fwrite(dpi_prefix,sizeof(dpi_prefix),1,maze);
sprintf((char *) ascii_equivalent,"%d",DOTS_PER_INCH);
#if EBCDIC
char_ptr=&(ascii_equivalent[0]);
while (*char_ptr)
{
(*char_ptr)-=192;
char_ptr++;
}
#endif
fwrite(&(ascii_equivalent[0]),strlen((char *) ascii_equivalent),1,
maze);
fwrite(&dpi_suffix,sizeof(dpi_suffix),1,maze);
fwrite(logical_mode,sizeof(logical_mode),1,maze);
slice_y_start=0;
while (slice_y_start <= Y_DOT_MAX)
{
slice_y_stop=slice_y_start+ROWS_PER_SLICE-1;
if (slice_y_stop > Y_DOT_MAX)
slice_y_stop=Y_DOT_MAX;
for (row_num=0; row_num < ROWS_PER_SLICE; row_num++)
for (column_num=0; column_num <= X_BYTE_MAX; column_num++)
row_ptr[row_num]->column[column_num]=0;
plot(&prime_tail,&y_prime_min,&y_prime_max,&z_prime_min,
&z_prime_max,&max_y_out,&max_z_out);
row_num=0;
for (slice_y=slice_y_start; slice_y <= slice_y_stop; slice_y++)
{
starting_column_num=0;
non_null_found=FALSE;
while ((starting_column_num <= X_BYTE_MAX)
&& (! non_null_found))
if (row_ptr[row_num]->column[starting_column_num] == 0)
starting_column_num++;
else
non_null_found=TRUE;
if (non_null_found)
{
non_null_found=FALSE;
ending_column_num=X_BYTE_MAX;
while ((ending_column_num >= 0) && (! non_null_found))
if (row_ptr[row_num]->column[ending_column_num] == 0)
ending_column_num--;
else
non_null_found=TRUE;
fwrite(cursor_x_prefix,sizeof(cursor_x_prefix),1,maze);
cursor_x=DOTS_PER_STROKE*8*starting_column_num;
sprintf((char *) ascii_equivalent,"%d",cursor_x);
#if EBCDIC
char_ptr=&(ascii_equivalent[0]);
while (*char_ptr)
{
(*char_ptr)-=192;
char_ptr++;
}
#endif
fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
maze);
fwrite(&cursor_x_suffix,sizeof(cursor_x_suffix),1,maze);
fwrite(cursor_y_prefix,sizeof(cursor_y_prefix),1,maze);
cursor_y=DOTS_PER_STROKE*slice_y;
sprintf(ascii_equivalent,"%d",cursor_y);
#if EBCDIC
char_ptr=&(ascii_equivalent[0]);
while (*char_ptr)
{
(*char_ptr)-=192;
char_ptr++;
}
#endif
fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
maze);
fwrite(&cursor_y_suffix,sizeof(cursor_y_suffix),1,maze);
fwrite(raster_prefix,sizeof(raster_prefix),1,maze);
fwrite(row_prefix,sizeof(row_prefix),1,maze);
num_bytes=ending_column_num-starting_column_num+1;
sprintf(ascii_equivalent,"%d",num_bytes);
#if EBCDIC
char_ptr=&(ascii_equivalent[0]);
while (*char_ptr)
{
(*char_ptr)-=192;
char_ptr++;
}
#endif
fwrite(&(ascii_equivalent[0]),strlen(ascii_equivalent),1,
maze);
fwrite(&row_suffix,sizeof(row_suffix),1,maze);
fwrite(&(row_ptr[row_num]->column[starting_column_num]),
num_bytes,1,maze);
fwrite(raster_suffix,sizeof(raster_suffix),1,maze);
}
row_num++;
}
slice_y_start+=ROWS_PER_SLICE;
}
fwrite(&formfeed,sizeof(formfeed),1,maze);
fclose(maze);
while (prime_head != NULL)
{
prime_ptr=prime_head->greater_x;
free(prime_head);
prime_head=prime_ptr;
}
for (row_num=0; row_num < ROWS_PER_SLICE; ++row_num)
free(row_ptr[row_num]);
}
}
static void add_room()
{
unsigned char delta_index_1;
unsigned char delta_index_2;
page[y][x]=' ';
delta_index_1=0;
do
{
delta_index_2=(unsigned char) r_n[0];
r_n_index_1=0;
for (r_n_index_2=1; r_n_index_2 < 8; ++r_n_index_2)
{
tem_int=r_n[r_n_index_2];
r_n[r_n_index_1]=tem_int;
delta_index_2+=(unsigned char) tem_int;
if (delta_index_2 >= 29)
delta_index_2-=29;
r_n_index_1=r_n_index_2;
}
r_n[7]=delta_index_2;
}
while (delta_index_2 >= 24);
while (delta_index_1 < 4)
{
x_next=x+2*delta_x[delta_index_1][delta_index_2];
if ((x_next <= 0) || (x_next >= MAX_X))
delta_index_1++;
else
{
y_next=y+2*delta_y[delta_index_1][delta_index_2];
if ((y_next <= 0) || (y_next >= MAX_Y))
delta_index_1++;
else
if (page[y_next][x_next] == 'W')
{
if (x == x_next)
{
y_wall_1=(y+y_next)/2;
page[y_wall_1][x_next]=' ';
}
else
{
x_wall_1=(x+x_next)/2;
page[y_next][x_wall_1]=' ';
}
x=x_next;
y=y_next;
add_room();
x-=2*delta_x[delta_index_1][delta_index_2];
y-=2*delta_y[delta_index_1][delta_index_2];
}
else
delta_index_1++;
}
}
}
static double f(x,y)
double x;
double y;
{
register int x_out;
register int y_out;
static double z;
y_out=((int) x)-2;
if (y_out < 0)
z=0.0;
else
if (y_out > 2*MAX_Y+1)
z=0.0;
else
{
x_out=((int) y)-2;
if (x_out < 0)
z=0.0;
else
if (x_out > 2*MAX_X+1)
z=0.0;
else
if (page[y_out/2][x_out/2] == 'W')
z=7.0;
else
z=0.0;
}
return(z);
}
static void evaluate_and_transform(x_min,x_max,y_min,y_max,num_x_divisions,
num_y_divisions,rotation,tilt,prime_cornor,prime_head,prime_tail,x_prime_max,
y_prime_min,y_prime_max,z_prime_min,z_prime_max,fatal_error)
double *x_min;
double *x_max;
double *y_min;
double *y_max;
int *num_x_divisions;
int *num_y_divisions;
double *rotation;
double *tilt;
prime_rec_ptr *prime_cornor;
prime_rec_ptr *prime_head;
prime_rec_ptr *prime_tail;
double *x_prime_max;
double *y_prime_min;
double *y_prime_max;
double *z_prime_min;
double *z_prime_max;
int *fatal_error;
{
static double cos_rotation;
static double cos_tilt;
static double delta_x;
static double delta_y;
static prime_rec_ptr last_prime_ptr;
static prime_rec_ptr prime_ptr;
static double radians;
static double radians_per_degree;
static prime_rec_ptr left;
static double sin_rotation;
static double sin_tilt;
static up_rec_ptr up_head;
static up_rec_ptr up_ptr;
static up_rec_ptr up_tail;
static double x;
register int x_division_num;
static double y;
register int y_division_num;
static double x_rotated;
static double z;
radians_per_degree=atan((double) 1.0)/45.0;
radians=(*tilt)*radians_per_degree;
cos_tilt=cos(radians);
sin_tilt=sin(radians);
radians=(*rotation)*radians_per_degree;
cos_rotation=cos(radians);
sin_rotation=sin(radians);
z=f(*x_min,*y_min);
x_rotated=(*x_min)*cos_rotation+(*y_min)*sin_rotation;
(*y_prime_min)=-(*x_min)*sin_rotation+(*y_min)*cos_rotation;
(*z_prime_min)=-x_rotated*sin_tilt+z*cos_tilt;
(*x_prime_max)=x_rotated*cos_tilt+z*sin_tilt;
(*y_prime_max)=(*y_prime_min);
(*z_prime_max)=(*z_prime_min);
last_prime_ptr=NULL;
delta_x=(double) (*num_x_divisions);
delta_x=((*x_max)-(*x_min))/delta_x;
delta_y=(double) (*num_y_divisions);
delta_y=((*y_max)-(*y_min))/delta_y;
up_head=NULL;
up_tail=NULL;
for (y_division_num=1;
((y_division_num <= (*num_y_divisions)) && (! *fatal_error));
++y_division_num)
{
if ((up_ptr=(up_rec *) malloc(sizeof(up_rec))) == NULL)
{
*fatal_error=TRUE;
printf("\n Fatal error: out of memory\n");
}
else
{
up_ptr->up=NULL;
if (up_head == NULL)
{
up_head=up_ptr;
up_ptr->previous=NULL;
}
else
{
up_tail->next=up_ptr;
up_ptr->previous=up_tail;
}
up_ptr->next=NULL;
up_tail=up_ptr;
}
}
x=(*x_min);
for (x_division_num=1;
((x_division_num <= (*num_x_divisions)) && (! *fatal_error));
++x_division_num)
{
left=NULL;
up_ptr=up_head;
y=(*y_min);
for (y_division_num=1;
((y_division_num <= (*num_y_divisions)) && (! *fatal_error));
++y_division_num)
{
z=f(x,y);
if ((prime_ptr=(prime_rec *) malloc(sizeof(prime_rec)))
== NULL)
{
*fatal_error=TRUE;
printf("\n Fatal error: out of memory\n");
}
else
{
prime_ptr->left=left;
if (z > 0.0)
prime_ptr->base_z=(char) 1;
else
prime_ptr->base_z=(char) 0;
if (left != NULL)
left->right=prime_ptr;
if (up_ptr->up != NULL)
up_ptr->up->down=prime_ptr;
x_rotated=x*cos_rotation+y*sin_rotation;
prime_ptr->y=-x*sin_rotation+y*cos_rotation;
prime_ptr->x=x_rotated*cos_tilt+z*sin_tilt;
prime_ptr->z=-x_rotated*sin_tilt+z*cos_tilt;
if (prime_ptr->x > (*x_prime_max))
(*x_prime_max)=prime_ptr->x;
if (prime_ptr->y < (*y_prime_min))
(*y_prime_min)=prime_ptr->y;
if (prime_ptr->y > (*y_prime_max))
(*y_prime_max)=prime_ptr->y;
if (prime_ptr->z < (*z_prime_min))
(*z_prime_min)=prime_ptr->z;
if (prime_ptr->z > (*z_prime_max))
(*z_prime_max)=prime_ptr->z;
prime_ptr->lesser_x=NULL;
if (last_prime_ptr == NULL)
{
(*prime_tail)=prime_ptr;
(*prime_cornor)=prime_ptr;
prime_ptr->greater_x=NULL;
}
else
{
(*prime_head)->lesser_x=prime_ptr;
prime_ptr->greater_x=(*prime_head);
}
(*prime_head)=prime_ptr;
left=prime_ptr;
up_ptr->up=prime_ptr;
up_ptr=up_ptr->next;
last_prime_ptr=prime_ptr;
y+=delta_y;
}
}
if (! *fatal_error)
{
left->right=NULL;
x+=delta_x;
}
}
if (! *fatal_error)
while (up_head != NULL)
{
up_head->up->down=NULL;
up_ptr=up_head->next;
free(up_head);
up_head=up_ptr;
}
}
static void adjust_perspective(prime_cornor,prime_head,prime_tail,x_prime_max,
y_prime_min,y_prime_max,z_prime_min,z_prime_max,fatal_error)
prime_rec_ptr *prime_cornor;
prime_rec_ptr *prime_head;
prime_rec_ptr *prime_tail;
double *x_prime_max;
double *y_prime_min;
double *y_prime_max;
double *z_prime_min;
double *z_prime_max;
int *fatal_error;
{
static double delta_x;
static double delta_y;
static double delta_z;
register int finished;
static prime_rec_ptr last_prime_ptr;
static prime_rec_ptr left;
static prime_rec_ptr new_prime_head;
static prime_rec_ptr new_prime_ptr;
static prime_rec_ptr new_prime_tail;
static prime_rec_ptr next_prime_row;
static prime_rec_ptr prime_column;
static prime_rec_ptr prime_ptr;
static prime_rec_ptr prime_row;
static up_rec_ptr up_head;
static up_rec_ptr up_ptr;
static up_rec_ptr up_tail;
static double x_eye;
static double y_center;
static double z_center;
if (((*y_prime_max)-(*y_prime_min)) > ((*z_prime_max)-(*z_prime_min)))
x_eye=2.0*((*y_prime_max)-(*y_prime_min))+(*x_prime_max);
else
x_eye=2.0*((*z_prime_max)-(*z_prime_min))+(*x_prime_max);
if (x_eye != (*x_prime_max))
{
up_head=NULL;
up_tail=NULL;
prime_column=(*prime_cornor);
while ((prime_column != NULL) && (! *fatal_error))
{
if ((up_ptr=(up_rec *) malloc(sizeof(up_rec))) == NULL)
{
*fatal_error=TRUE;
printf("\n Fatal error: out of memory\n");
}
else
{
up_ptr->up=NULL;
if (up_head == NULL)
{
up_head=up_ptr;
up_ptr->previous=NULL;
}
else
{
up_tail->next=up_ptr;
up_ptr->previous=up_tail;
}
up_ptr->next=NULL;
up_tail=up_ptr;
prime_column=prime_column->right;
}
}
y_center=(double) ((*y_prime_max)+(*y_prime_min))/2.0;
z_center=(double) ((*z_prime_max)+(*z_prime_min))/2.0;
last_prime_ptr=NULL;
new_prime_head=NULL;
new_prime_tail=NULL;
prime_row=(*prime_cornor);
while ((prime_row != NULL) && (! *fatal_error))
{
left=NULL;
up_ptr=up_head;
next_prime_row=prime_row->down;
prime_column=prime_row;
while ((prime_column != NULL) && (! *fatal_error))
{
if ((new_prime_ptr=(prime_rec *) malloc(sizeof(prime_rec)))
== NULL)
{
*fatal_error=TRUE;
printf("\n Fatal error: out of memory\n");
}
else
{
new_prime_ptr->left=left;
new_prime_ptr->base_z=prime_column->base_z;
if (left != NULL)
left->right=new_prime_ptr;
if (up_ptr->up != NULL)
up_ptr->up->down=new_prime_ptr;
delta_x=prime_column->x-x_eye;
delta_y=prime_column->y-y_center;
delta_z=prime_column->z-z_center;
new_prime_ptr->x
=sqrt(delta_x*delta_x+delta_y*delta_y+delta_z*delta_z);
new_prime_ptr->y
=y_center+(double)(prime_column->y-y_center)
*(x_eye-(*x_prime_max))/(x_eye-prime_column->x);
new_prime_ptr->z
=z_center+(double)(prime_column->z-z_center)
*(x_eye-(*x_prime_max))/(x_eye-prime_column->x);
if (last_prime_ptr == NULL)
{
new_prime_head=new_prime_ptr;
new_prime_tail=new_prime_ptr;
new_prime_ptr->lesser_x=NULL;
new_prime_ptr->greater_x=NULL;
}
else
if (new_prime_ptr->x < last_prime_ptr->x)
{
finished=FALSE;
while (! finished)
{
last_prime_ptr=last_prime_ptr->lesser_x;
if (last_prime_ptr == NULL)
finished=TRUE;
else
{
if (new_prime_ptr->x >= last_prime_ptr->x)
finished=TRUE;
}
}
new_prime_ptr->lesser_x=last_prime_ptr;
if (last_prime_ptr == NULL)
{
new_prime_head->lesser_x=new_prime_ptr;
new_prime_ptr->greater_x=new_prime_head;
new_prime_head=new_prime_ptr;
}
else
{
new_prime_ptr->greater_x
=last_prime_ptr->greater_x;
last_prime_ptr->greater_x->lesser_x
=new_prime_ptr;
last_prime_ptr->greater_x=new_prime_ptr;
}
}
else
{
finished=FALSE;
while (! finished)
{
last_prime_ptr=last_prime_ptr->greater_x;
if (last_prime_ptr == NULL)
finished=TRUE;
else
{
if (new_prime_ptr->x <= last_prime_ptr->x)
finished=TRUE;
}
}
new_prime_ptr->greater_x=last_prime_ptr;
if (last_prime_ptr == NULL)
{
new_prime_tail->greater_x=new_prime_ptr;
new_prime_ptr->lesser_x=new_prime_tail;
new_prime_tail=new_prime_ptr;
}
else
{
new_prime_ptr->lesser_x
=last_prime_ptr->lesser_x;
last_prime_ptr->lesser_x->greater_x
=new_prime_ptr;
last_prime_ptr->lesser_x=new_prime_ptr;
}
}
}
if (! *fatal_error)
{
left=new_prime_ptr;
up_ptr->up=new_prime_ptr;
up_ptr=up_ptr->next;
last_prime_ptr=new_prime_ptr;
prime_ptr=prime_column->right;
free(prime_column);
prime_column=prime_ptr;
}
}
if (! *fatal_error)
{
left->right=NULL;
prime_row=next_prime_row;
}
}
if (! *fatal_error)
{
(*prime_head)=new_prime_head;
(*prime_tail)=new_prime_tail;
while (up_head != NULL)
{
up_head->up->down=NULL;
up_ptr=up_head->next;
free(up_head);
up_head=up_ptr;
}
}
}
}
static void pset(x,y,shading)
int *x;
int *y;
int shading;
{
register int bit_num;
register int byte_num;
static int dot;
static int slice_y;
if ((*y) >= slice_y_start)
{
if ((*y) <= slice_y_stop)
{
byte_num=(*x)/8;
bit_num=(*x)-8*byte_num;
switch (shading)
{
case 0:
switch ((*y) % 4)
{
case 0:
if (((*x) % 4) == 3)
dot=TRUE;
else
dot=FALSE;
break;
case 1:
if (((*x) % 4) == 1)
dot=TRUE;
else
dot=FALSE;
break;
case 2:
if (((*x) % 4) == 2)
dot=TRUE;
else
dot=FALSE;
break;
default:
if (((*x) % 4) == 0)
dot=TRUE;
else
dot=FALSE;
break;
}
break;
case 1:
if ((*y) % 2)
if (((*x) % 4) == 1)
dot=TRUE;
else
dot=FALSE;
else
if ((*x) % 2)
dot=FALSE;
else
dot=TRUE;
break;
case 2:
if ((*y) % 2)
if ((*x) % 2)
dot=TRUE;
else
dot=FALSE;
else
if ((*x) % 2)
dot=FALSE;
else
dot=TRUE;
break;
default:
dot=TRUE;
break;
};
slice_y=(*y)-slice_y_start;
if (dot)
row_ptr[slice_y]->column[byte_num]
=(row_ptr[slice_y]->column[byte_num] | black[bit_num]);
else
row_ptr[slice_y]->column[byte_num]
=(row_ptr[slice_y]->column[byte_num] & white[bit_num]);
}
}
}
static void draw_line(x1,y1,x2,y2,shading)
int *x1;
int *y1;
int *x2;
int *y2;
int shading;
{
static int error;
static int error_prime_x;
static int error_prime_y;
register int permissible_delta_x;
register int permissible_delta_y;
static int x;
static int x_diff;
static int y;
static int y_diff;
if ((*x2) >= (*x1))
permissible_delta_x=1;
else
permissible_delta_x=-1;
if ((*y2) >= (*y1))
permissible_delta_y=1;
else
permissible_delta_y=-1;
x=(*x1);
y=(*y1);
x_diff=(*x2)-(*x1);
y_diff=(*y2)-(*y1);
error=0;
pset(&x,&y,shading);
while ((x != (*x2)) || (y != (*y2)))
{
error_prime_x=error+permissible_delta_x*y_diff;
error_prime_y=error-permissible_delta_y*x_diff;
if (abs(error_prime_x) <= abs(error_prime_y))
{
x+=permissible_delta_x;
error=error_prime_x;
}
else
{
y+=permissible_delta_y;
error=error_prime_y;
}
pset(&x,&y,shading);
}
}
static void plot(prime_tail,y_prime_min,y_prime_max,z_prime_min,z_prime_max,
max_y_out,max_z_out)
prime_rec_ptr *prime_tail;
double *y_prime_min;
double *y_prime_max;
double *z_prime_min;
double *z_prime_max;
int *max_y_out;
int *max_z_out;
{
static pointtype box [4];
static long box_delta_x;
static long box_delta_y;
register int box_num_1;
register int box_num_2;
static long box_x_intercept;
static int box_x1;
static int box_x2;
static int box_y_max;
static int box_y_min;
static long box_y_offset;
static int box_y1;
static int intercept_count_mod_2;
static int line_x1;
static int line_x2;
static int line_y1;
static int line_y2;
static double pixels_per_unit;
static prime_rec_ptr prime_ptr;
static int shading;
static double y_offset;
static double y_out_max;
static double z_offset;
static double z_out_max;
y_out_max=(double) (*max_y_out);
z_out_max=(double) (*max_z_out);
if (z_out_max*((*y_prime_max)-(*y_prime_min))
> y_out_max*((*z_prime_max)-(*z_prime_min)))
{
pixels_per_unit=y_out_max/((*y_prime_max)-(*y_prime_min));
y_offset=0.0;
z_offset
=-(z_out_max-pixels_per_unit*((*z_prime_max)-(*z_prime_min)))/2.0;
}
else
if (z_out_max*((*y_prime_max)-(*y_prime_min))
< y_out_max*((*z_prime_max)-(*z_prime_min)))
{
pixels_per_unit=z_out_max/((*z_prime_max)-(*z_prime_min));
y_offset
=(y_out_max-pixels_per_unit*((*y_prime_max)-(*y_prime_min)))/2.0;
z_offset=0.0;
}
else
/* plot degenerates to a single point */
{
pixels_per_unit=1.0;
y_offset=y_out_max/2.0;
z_offset=-z_out_max/2.0;
}
prime_ptr=(*prime_tail);
while ((prime_ptr != NULL))
{
if ((prime_ptr->right != NULL))
{
if ((prime_ptr->down != NULL))
{
box[0].x=(int) (y_offset+pixels_per_unit
*(prime_ptr->y-(*y_prime_min)));
box[0].y=(int) (z_offset+z_out_max-pixels_per_unit
*(prime_ptr->z-(*z_prime_min)));
box[1].x=(int) (y_offset+pixels_per_unit
*(prime_ptr->right->y-(*y_prime_min)));
box[1].y=(int) (z_offset+z_out_max-pixels_per_unit
*(prime_ptr->right->z-(*z_prime_min)));
box[3].x=(int) (y_offset+pixels_per_unit
*(prime_ptr->down->y-(*y_prime_min)));
box[3].y=(int) (z_offset+z_out_max-pixels_per_unit
*(prime_ptr->down->z-(*z_prime_min)));
box[2].x=(int) (y_offset+pixels_per_unit
*(prime_ptr->down->right->y-(*y_prime_min)));
box[2].y=(int) (z_offset+z_out_max-pixels_per_unit
*(prime_ptr->down->right->z-(*z_prime_min)));
box_y_min=box[0].y;
box_y_max=box_y_min;
if ((prime_ptr->base_z == (char) 1)
&& (prime_ptr->right->base_z == (char) 1)
&& (prime_ptr->down->base_z == (char) 1)
&& (prime_ptr->down->right->base_z == (char) 1))
shading=0;
else
if ((prime_ptr->base_z == (char) 0)
&& (prime_ptr->right->base_z == (char) 0)
&& (prime_ptr->down->base_z == (char) 0)
&& (prime_ptr->down->right->base_z == (char) 0))
shading=1;
else
if ((prime_ptr->base_z == (char) 1)
&& (prime_ptr->right->base_z == (char) 1)
&& (prime_ptr->down->base_z == (char) 0)
&& (prime_ptr->down->right->base_z == (char) 0))
shading=2;
else
if ((prime_ptr->base_z == (char) 1)
&& (prime_ptr->right->base_z == (char) 0)
&& (prime_ptr->down->base_z == (char) 1)
&& (prime_ptr->down->right->base_z == (char) 0))
shading=3;
else
if ((prime_ptr->down->down == NULL)
&& (prime_ptr->base_z == (char) 0))
shading=1;
else
shading=2;
for (box_num_1=1; box_num_1 < 4; ++box_num_1)
{
if (box[box_num_1].y < box_y_min)
box_y_min=box[box_num_1].y;
if (box[box_num_1].y > box_y_max)
box_y_max=box[box_num_1].y;
}
for (box_y1=box_y_min; box_y1 <= box_y_max; ++box_y1)
{
intercept_count_mod_2=0;
box_num_2=1;
for (box_num_1=0; box_num_1 < 4; ++box_num_1)
{
if (box[box_num_1].y >= box_y1)
{
if (box_y1 > box[box_num_2].y)
{
box_delta_y=box[box_num_2].y-box[box_num_1].y;
box_delta_x=box[box_num_2].x-box[box_num_1].x;
box_y_offset=box_y1-box[box_num_1].y;
box_x_intercept=box[box_num_1].x;
box_x1=(int) ((box_delta_x*box_y_offset)
/box_delta_y+box_x_intercept);
if (intercept_count_mod_2 == 0)
box_x2=box_x1;
else
{
if (box_x1 < box_x2)
{
line_x1=box_x1;
line_x2=box_x2;
}
else
{
line_x1=box_x2;
line_x2=box_x1;
}
pset(&line_x1,&box_y1,shading);
while (line_x1 < line_x2)
{
line_x1++;
pset(&line_x1,&box_y1,shading);
}
}
intercept_count_mod_2=1-intercept_count_mod_2;
}
}
else
{
if (box_y1 <= box[box_num_2].y)
{
box_delta_y=box[box_num_2].y-box[box_num_1].y;
box_delta_x=box[box_num_2].x-box[box_num_1].x;
box_y_offset=box_y1-box[box_num_1].y;
box_x_intercept=box[box_num_1].x;
box_x1=(int) ((box_delta_x*box_y_offset)
/box_delta_y+box_x_intercept);
if (intercept_count_mod_2 == 0)
box_x2=box_x1;
else
{
if (box_x1 < box_x2)
{
line_x1=box_x1;
line_x2=box_x2;
}
else
{
line_x1=box_x2;
line_x2=box_x1;
}
pset(&line_x1,&box_y1,shading);
while (line_x1 < line_x2)
{
line_x1++;
pset(&line_x1,&box_y1,shading);
}
}
intercept_count_mod_2=1-intercept_count_mod_2;
}
}
box_num_2++;
if (box_num_2 >= 4)
box_num_2=0;
}
}
box_num_2=1;
for (box_num_1=0; box_num_1 < 4; ++box_num_1)
{
line_x1=box[box_num_1].x;
line_y1=box[box_num_1].y;
line_x2=box[box_num_2].x;
line_y2=box[box_num_2].y;
box_num_2++;
draw_line(&line_x1,&line_y1,&line_x2,&line_y2,shading);
if (box_num_2 >= 4)
box_num_2=0;
}
if ((prime_ptr->base_z == (char) 1)
&& (prime_ptr->right->base_z == (char) 1)
&& (prime_ptr->down->base_z == (char) 0)
&& (prime_ptr->down->right->base_z == (char) 0))
{
if (prime_ptr->left != NULL)
{
if (prime_ptr->left->base_z == (char) 0)
{
shading=0;
line_x1=box[0].x;
line_y1=box[0].y;
line_x2=box[3].x;
line_y2=box[3].y;
draw_line(&line_x1,&line_y1,&line_x2,&line_y2,
shading);
}
}
}
}
}
prime_ptr=prime_ptr->lesser_x;
}
}